名字空间组合

  我们常常需要从现存的界面出发组合出新的界面,例如,

    namespace His_string {
        class String { /* ... */ };
        String operator+(const String&, const String&);
        String operator+(const String&, const char*);
        void fill(char);
        // ...
    }

    namespace Her_vector {
        template<class T> class Vector { /* ... */ };
        // ...
    }

    namespace My_lib {
        using namespace His_string;
        using namespace Her_vector;
        void my_fct(String&);
    }

有了这些,我们就可以在My_lib的基础上写程序了:

    void f()
    {
        My_lib::String s = "Byron";        // 找到My_lib::His_string::String
        // ...
    }

    using namespace My_lib;
    void g(Vector<String>& vs)
    {
        // ...
        my_fct(vs[5]);
        // ...
    }

如果显式限定的名字(例如,My_lib::String)在所说的名字空间里没有声明,编译器就会去查看使用指令说到的名字空间(例如,His_string)。

  仅当我们需要去定义什么东西时,才需要知道一个实体真正所在的名字空间:

    void My_lib::fill(char c)        // 错误❌:在My_lib里没有声明fill()
    {
        // ...
    }
    void His_string::fill(char c)    // 可以:fill()在His_string里声明
    {
        // ...
    }
    void My_lib::my_fct(String& v)    // 可以:String是My_lib::String,意思是His_string::String
    {
        // ...
    }

按理想情况,一个名字空间应该:

1)、描述了一个具有逻辑统一性的特征集合。
2)、不为用户提供对无关特征的访问。
3)、不给用户强加任何明显的记述负担。

这里和下面几小节中给出的组合技术---与#include机制(9.2.1节)一起---对上述思想提供了强有力的支持。

🔚